package com.pzr.soccer.uitl;

import com.pzr.soccer.domain.game.Game;

import java.util.HashMap;
import java.util.Map;
import java.util.NavigableMap;
import java.util.function.BiFunction;

/**
 * @Author pzr
 * @date:2021-12-09-18:45
 * @Description:
 **/

public class MatchCalculator {
    public static final String Match_FirstHalf_End = "半场结束";
    public static final String Match_Full_End = "全场结束";

    public static final String Match_TotalShot = "totalShot";
    public static final String Match_GapShot = "gapShot";
    public static final String Match_MinShot = "minShot";
    public static final String Match_MaxShot = "maxShot";
    public static final String Match_TotalDanger = "totalDanger";
    public static final String Match_GapDanger = "gaoDanger";
    public static final String Match_MinDanger = "minDanger";
    public static final String Match_MaxDanger = "maxDanger";
    public static final String Match_Teams = "teams";
    public static final String Match_Leagues = "leagues";
    public static final String Match_Date = "date";
    public static final String Match_Time = "time";

        public static final String Match_Result_Goal = "result_goal";
    public static final String Match_Result_Corner = "result_corner";
    public static final String Match_Strong_Result_Goal = "strong_result_goal";
    public static final String Match_Strong_Result_Corner = "strong_result_corner";


    private static int totalPair(int begin, int end, NavigableMap<Integer, int[]> map) {
        return homeIndex(begin, end, map) + awayIndex(begin, end, map);
    }

    private static int gapPair(int begin, int end, NavigableMap<Integer, int[]> map) {
        return Math.abs(homeIndex(begin, end, map) - awayIndex(begin, end, map));
    }

    private static int maxPair(int begin, int end, NavigableMap<Integer, int[]> map) {
        return Math.max(awayIndex(begin, end, map), homeIndex(begin, end, map));
    }

    private static int minPair(int begin, int end, NavigableMap<Integer, int[]> map) {
        return Math.min(awayIndex(begin, end, map), homeIndex(begin, end, map));
    }

    private static int homeIndex(int begin, int end, NavigableMap<Integer, int[]> map) {
        if (map.isEmpty()) {
            return 0;
        }
        int[] arr_begin = map.floorEntry(begin) != null ? map.floorEntry(begin).getValue() : new int[]{0, 0};
        int[] arr_end = map.floorEntry(end) != null ? map.floorEntry(end).getValue() : new int[]{0, 0};
        return arr_end[0] - arr_begin[0];
    }

    private static int awayIndex(int begin, int end, NavigableMap<Integer, int[]> map) {
        if (map.isEmpty()) {
            return 0;
        }
        int[] arr_begin = map.floorEntry(begin) != null ? map.floorEntry(begin).getValue() : new int[]{0, 0};
        int[] arr_end = map.floorEntry(end) != null ? map.floorEntry(end).getValue() : new int[]{0, 0};
        return arr_end[1] - arr_begin[1];
    }

    private static Map<String, BiFunction<Game, int[], Object>> map() {
        Map<String, BiFunction<Game, int[], Object>> map = new HashMap<>();
        map.put(Match_TotalShot, (game, arr) -> totalPair(arr[0], arr[1], game.getPairShot()));
        map.put(Match_GapShot, (game, arr) -> gapPair(arr[0], arr[1], game.getPairShot()));
        map.put(Match_MinShot, (game, arr) -> minPair(arr[0], arr[1], game.getPairShot()));
        map.put(Match_MaxShot, (game, arr) -> maxPair(arr[0], arr[1], game.getPairShot()));

        map.put(Match_TotalDanger, (game, arr) -> totalPair(arr[0], arr[1], game.getPairDanger()));
        map.put(Match_GapDanger, (game, arr) -> gapPair(arr[0], arr[1], game.getPairDanger()));
        map.put(Match_MinDanger, (game, arr) -> minPair(arr[0], arr[1], game.getPairDanger()));
        map.put(Match_MaxDanger, (game, arr) -> maxPair(arr[0], arr[1], game.getPairDanger()));

        map.put(Match_Teams, (game, arr) -> game.getHome()+"VS"+game.getAway());
        map.put(Match_Leagues, (game, arr) -> game.getLeague());
        map.put(Match_Date, (game, arr) -> game.getKickOff().toLocalDate());
        map.put(Match_Time, (game, arr) -> game.getKickOff().toLocalTime());

        map.put(Match_Result_Goal, (game, arr) -> totalPair(0, 200, game.getPairScore()));
        map.put(Match_Result_Corner, (game, arr) -> totalPair(0, 200, game.getPairCorner()));

        map.put(Match_Strong_Result_Goal, (game, arr) -> {
            if(game.getStrongTeam().equals("home")){
                return homeIndex(0,200,game.getPairScore());
            }else {
                return awayIndex(0,200,game.getPairScore());
            }
        });

        map.put(Match_Strong_Result_Corner, (game, arr) -> {
            if(game.getStrongTeam().equals("home")){
                return homeIndex(0,200,game.getPairCorner());
            }else {
                return awayIndex(0,200,game.getPairCorner());
            }
        });
        return map;
    }

    public static Object calculate(String target,Game game,int[] arr){
        return map().get(target).apply(game,arr);
    }
}
